# -*- coding: utf-8 -*-
"""
加密工具模块
"""
import os
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from config import ENCRYPTION_KEY_LENGTH
from .path_manager import get_app_data_dir

class EncryptionManager:
    """加密管理器"""
    
    def __init__(self):
        self.key_file = os.path.join(get_app_data_dir(), "encryption.key")
        self._ensure_key_file()
        self._load_key()
    
    def _ensure_key_file(self):
        """确保密钥文件存在"""
        key_dir = os.path.dirname(self.key_file)
        if not os.path.exists(key_dir):
            os.makedirs(key_dir)
        
        if not os.path.exists(self.key_file):
            self._generate_key()
    
    def _generate_key(self):
        """生成加密密钥"""
        # 使用固定的盐值和密码生成密钥，确保在不同环境中保持一致
        salt = b"mysql_dict_2024_salt"  # 固定盐值
        
        # 使用PBKDF2生成密钥
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=100000,
        )
        
        # 使用固定的密码生成密钥
        password = b"mysql_dict_export_tool_2024"
        key = base64.urlsafe_b64encode(kdf.derive(password))
        
        # 保存密钥和盐值
        with open(self.key_file, 'wb') as f:
            f.write(salt + key)
    
    def _load_key(self):
        """加载加密密钥"""
        try:
            with open(self.key_file, 'rb') as f:
                data = f.read()
            
            salt = data[:20]  # 固定盐值长度
            key = data[20:]
            
            # 验证密钥
            kdf = PBKDF2HMAC(
                algorithm=hashes.SHA256(),
                length=32,
                salt=salt,
                iterations=100000,
            )
            
            password = b"mysql_dict_export_tool_2024"
            expected_key = base64.urlsafe_b64encode(kdf.derive(password))
            
            if key == expected_key:
                self.fernet = Fernet(key)
            else:
                # 密钥验证失败，重新生成
                self._generate_key()
                self._load_key()
        except Exception as e:
            print(f"加载密钥失败: {e}")
            # 如果加载失败，重新生成
            self._generate_key()
            self._load_key()
    
    def encrypt_password(self, password):
        """加密密码"""
        try:
            encrypted_password = self.fernet.encrypt(password.encode('utf-8'))
            return base64.b64encode(encrypted_password).decode('utf-8')
        except Exception as e:
            print(f"密码加密失败: {e}")
            return None
    
    def decrypt_password(self, encrypted_password):
        """解密密码"""
        try:
            encrypted_data = base64.b64decode(encrypted_password.encode('utf-8'))
            decrypted_password = self.fernet.decrypt(encrypted_data)
            return decrypted_password.decode('utf-8')
        except Exception as e:
            print(f"密码解密失败: {e}")
            return None
    
    def hash_password(self, password):
        """哈希密码（用于用户密码）"""
        from cryptography.hazmat.primitives import hashes
        from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
        import base64
        
        salt = os.urandom(16)
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=100000,
        )
        
        key = kdf.derive(password.encode('utf-8'))
        return base64.urlsafe_b64encode(salt + key).decode('utf-8')
    
    def verify_password(self, password, hashed_password):
        """验证密码"""
        try:
            from cryptography.hazmat.primitives import hashes
            from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
            import base64
            
            data = base64.urlsafe_b64decode(hashed_password.encode('utf-8'))
            salt = data[:16]
            
            kdf = PBKDF2HMAC(
                algorithm=hashes.SHA256(),
                length=32,
                salt=salt,
                iterations=100000,
            )
            
            key = kdf.derive(password.encode('utf-8'))
            expected_hash = base64.urlsafe_b64encode(salt + key).decode('utf-8')
            
            return hashed_password == expected_hash
        except Exception as e:
            print(f"密码验证失败: {e}")
            return False
